home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 626-637 / disk_635 / ldp / source / ldp.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  50KB  |  1,285 lines

  1. /*          Laser Disk Player program                *\
  2. **         Copyright Ron M. Battle 1991              **
  3. **            HyperBorea Studio B                    **
  4. **             Manx Aztec C v5.2a                    **
  5. ** May be freely distributed for non-commercial use  **
  6. **            *Revision History*                     **
  7. **---------------------------------------------------**
  8. **  DATE     VERSION  COMMENTS                       **
  9. **---------------------------------------------------**
  10. **  02-22-92  1.31    Add SerialUnit                 **
  11. **  02-15-92  1.3     Can run from WorkBench,        **
  12. **                     help key supported,           **
  13. **                     better error reporting,       **
  14. **                     ToolType defaults,            **
  15. **                     Thanx to Larry Shultz and     **
  16. **                     Brian Berg for LDP.info icons **
  17. **  10-13-91  1.21    Dressed up remote with examples**
  18. **                     from Brian Berg               **
  19. **  04-21-91  1.2     Generic Player revisions for   **
  20. **                     Hitachi, Pioneer, Sony        **
  21. **  09-29-90  1.1     Added ARexx interface          **
  22. **                     Thanx to GS & BH for FancyDemo**
  23. **  02-25-90  1.0     Sony players only              **
  24. **---------------------------------------------------**
  25. **  The onscreen controller only uses a subset of    **
  26. **  commands. This synchronous implementation is     **
  27. **  not slick, could have better error checking,     **
  28. **             but it WORKS!!                        **
  29. **  It would be nice to have more control over the   **
  30. **  serial device's buffer. As it stands, the min    **
  31. **  size is 512 bytes! This makes it more            **
  32. **  difficult to keep track of lid openings,etc.     **
  33. **  Since I'm synchronous, I don't check!            **
  34. **  You could get around this by doing a continual   **
  35. **  serial read with parameters for terminator char  **
  36. **  and number of chars expected on the read. You    **
  37. **  would need to modify the main event loop to also **
  38. **  wait for a message from mySerPort, but would be  **
  39. **  better to set up a new message port for serial   **
  40. **  reads! Use SendIO() for asynchronous reads,      **
  41. **  when read done GetMsg(), get any errors from this**
  42. **  msg then SendIO() another read, etc.!            **
  43. **                                                   **
  44. **  REMOTE CONTROLLER COMMANDS:                      **
  45. **                                                   **
  46. **  CL      Clear commands                           **
  47. **  Index   Toggle index display ON/OFF              **
  48. **  <<< >>> Scan                                     **
  49. **  << >>   Fast                                     **
  50. **  <| |>   Slow                                     **
  51. **  | < > | Step                                     **
  52. **  < >     Play                                     **
  53. **  Search  Search  Hitachi&Sony: Srch Frame# Enter  **
  54. **                  Pioneer: Frame# Srch             **
  55. **  Enter   Enter   For Hitachi&Sony players only    **
  56. **  Log     Log     saves note and frame# in         **
  57. **                  ram:LDP.log                      **
  58. **  M+      Memorize current frame number            **
  59. **  MR      Search for memorized frame number        **
  60. **  Still   Still frame                              **
  61. **  Eject   Eject disc                               **
  62. **                                                   **
  63. **  You can also enter numbers into the display and  **
  64. **  press return for a search.                       **
  65. **  If you don't do the commands in the proper       **
  66. **  sequence, you might hang the controller. If you  **
  67. **  don't like that.......CHANGE IT!                 **
  68. **  This controller also takes exclusive control     **
  69. **  of the serial.device. Shared access never worked **
  70. **  properly!                                        **
  71. **                                                   **
  72. \*                                                   */
  73.  
  74. #include <exec/exec.h>
  75. #include <intuition/intuition.h>
  76. #include <workbench/workbench.h>
  77. #include <workbench/startup.h>
  78. #include <workbench/icon.h>
  79. #include <devices/serial.h>
  80. #include <ctype.h>
  81. #include <stdio.h>
  82. #include <stdlib.h>
  83. #include <functions.h>
  84. #include <rexx/storage.h>
  85. #include "tinystring.h"     /* The C routine index() causes contention */
  86. #include "gadgets.h"
  87. #include "video.h"     /* this header would not pre-compile properly */
  88.  
  89.  
  90. /* #define DEBUG 1 */
  91.  
  92. #define HELP 95                    /* raw keycode for Help button */
  93.  
  94. /* defaults for serial device */
  95. #define READ_BITS   8
  96. #define WRITE_BITS  8
  97. #define STOP_BITS   1
  98. #define MIN_BAUD    1200
  99. #define MAX_BAUD    9600
  100. #define MIN_UNIT    0
  101. #define MAX_UNIT    31
  102.  
  103. /* errors */
  104. #define NO_ERR          0
  105. #define READ_EXTIO_ERR  1
  106. #define DEVICE_ERR      2
  107. #define WRITEPORT_ERR   3
  108. #define WRITE_EXTIO_ERR 4
  109. #define INT_ERR         5     /* error opening intuition library  */
  110. #define WIN_ERR         6    /*  error opening window            */
  111. #define REXX_ERR        7   /*   error creating rexx port       */
  112. #define ILIB_ERR        8  /*    error opening icon library    */
  113.  
  114. char *ErrStr[] = {
  115.                   "NONE!",
  116.                   "Allocating read i/o block! ",
  117.                   "Opening serial device! ",
  118.                   "Creating write port! ",
  119.                   "Allocating write i/o block! ",
  120.                   "Opening Intuition library!",
  121.                   "Opening window!",
  122.                   "Creating rexx port!",
  123.                   "Opening icon library!" };
  124.  
  125.  
  126. #define MAXIN         6              /* size of in-buffers */
  127. #define MAXOUT        22            /* size of out-buffer */
  128. #define LDP_1000A     2            /* for  SonyModel     */
  129. #define OTHER         1           /*  means 180,1200,1500, or 2000 models */
  130. #define ASLEEP        0          /*  ldp not ready     */
  131. #define MAX_FRAME     54000     /* highest frame #    */
  132. #define MAX_FRAME_STR "54000"  /*  "       " string  */
  133.  
  134. #define D7         128     /* bit 7, used for masking */
  135. #define D6          64
  136. #define D5          32
  137. #define D4          16
  138. #define D3           8
  139. #define D2           4
  140. #define D1           2
  141. #define D0           1
  142. #define NOT_READY  (D5 | D3 | D2)     /* if any bits set: NOT READY */
  143.  
  144. #define REVERSE 0
  145. #define FORWARD 1
  146. #define ADD     1
  147. #define NEW     0
  148. #define DTEXT   0
  149. #define DNUM    1
  150.  
  151. /* ARexx stuff */
  152. #define HOST_PORT_NAME  "LDP"
  153. struct MsgPort  *rexx_port      = NULL ;
  154. ULONG           RexxSigMask ;   /* signal mask used for WAIT() */
  155.  
  156. IMPORT struct Gadget EjectGad   ;    /* first gadget in list */
  157. IMPORT struct Gadget NumDisplayGad, TextDisplayGad ;
  158. IMPORT struct Gadget EnterGad   ;  /* will be disabled if pioneer player! */
  159. IMPORT UBYTE         NumBuff[NUMLEN], TextBuff[TEXTLEN] ;
  160.  
  161. struct MsgPort  *mySerPort = NULL ;
  162. struct IOExtSer *mySerReq  = NULL ;
  163. char   ScratchBuff[MAXOUT] ;
  164. char   inbuff[MAXIN], outbuff[MAXOUT], StatusBuffer[MAXIN] ;
  165. char   *version =  "$VER: LDP by HyperBorea Studio B  V1.31__22.02.92(" ;
  166. char   *CmdTerm = NULL ;         /* command terminator          */
  167. char   *PlayerMode = NULL ;     /* frame mode only for now     */
  168. char   MemAddr[MAXIN]  ;       /* address for remote memorize */
  169. char   CurrentAddr[MAXIN] ;   /* current address of player   */
  170. char   *GadStr[] = { "","","","","","","","","","",
  171.        "Eject","Enter","Search","Still","Clear","Index","Rplay","Fplay",
  172.        "Rstep","Fstep","Rslow","Fslow",
  173.        "Rfast","Ffast","Rscan","Fscan",
  174.        "Memorize","Msearch","Log to ram:*","",""} ;
  175. struct Window        *wp=NULL ;
  176. struct IntuitionBase *IntuitionBase=NULL ;
  177. struct IconBase      *IconBase=NULL ;
  178. ULONG  wakeupmask, UserSigMask ;
  179. BOOL   FscanDOWN = FALSE ;
  180. BOOL   RscanDOWN = FALSE ;
  181. BOOL   SearchPRESSED   = FALSE ;
  182. BOOL   SerDeviceACTIVE = FALSE ;
  183. BOOL   LdpREADY = TRUE  ;
  184. BOOL   IndexON  = TRUE  ;
  185. BOOL   ReversePolish = FALSE ;       /* Pioneer players do arg,verb            */
  186. BOOL   RemoteON = TRUE ;            /* onscreen remote controller             */
  187. BOOL   TimeToExit = FALSE ;        /* used to exit ProcessEvents()           */
  188. USHORT CurrentCmd = 0  ;          /* Current Command                        */
  189. USHORT SonyModel  = OTHER;       /* default                                */
  190. USHORT BaudRate  = 1200  ;      /* Fixed baud rate for SONY  LDP-1000A    */
  191. USHORT PlayerType = sony ;     /* default player                         */
  192. USHORT ReturnBytes       ;    /* number of bytes returned from command  */
  193. USHORT AddrBytes         ;   /* number of bytes returned address query */
  194. USHORT StatBytes         ;  /* number of bytes returned status query  */
  195. USHORT SerialUnit        ; /* serial port unit number                */
  196.  
  197. char   HelpStr[] = {"\n\
  198.       Laser Disc Player  by Ron M. Battle    HyperBorea Studio B\n\
  199. ------------------------------------------------------------------------------\n\
  200.   CLI USAGE: run ldp -bBaud -pPlayerType -rRemoteOn/Off -uSerialUnit#\n\
  201.     example: run ldp -b1200 -pSony       -rOn     -u0   (DEFAULT)\n\
  202.   WB  USAGE: ToolTypes: BAUD  PLAYER  REMOTE  WINDOW  UNIT\n\
  203.     example: BAUD=4800 PLAYER=PIONEER REMOTE=ON WINDOW=CON:20/20/320/70/LDP!\n\
  204. Public Port: LDP   (case sensitive)\n\
  205.        Note: On remote, click in text area, enter note and press LOG,\n\
  206.              current frame# and note will be saved to ram:LDP.log\n\
  207.        Help: Press Help key on keyboard!\n\
  208.  ARexx cmds:\n\
  209. address (returns frame# as 32 bit integer)  baud rate (set baud rate)\n\
  210. clear (clear all commands)  eject (open door)  enter (terminate some commands)\n\
  211. forward howfast (step/slow/fast/scan/normal)   frame (set frame mode)\n\
  212. index toggle (on/off)  init (initialize player)  play start end (play sequence)\n\
  213. quit (shut down program)  ready (returns 1 if player ready)\n\
  214. reverse howfast (step/slow/fast/scan/normal)  search frame# (ASCII digits)\n\
  215. still (still frame)\n\
  216. vplayer type (set player type: sony/hitachi/pioneer/none, returns 32 bit int)\n\n\
  217. \n CLI ARexx example:  rx 'address LDP play 5000 5100'\n\
  218. ------------------------------------------------------------------------------\n\n"};
  219.  
  220. struct NewWindow LdpWindow= {
  221.         10,10, /* window XY origin relative to TopLeft of screen */
  222.         200,162,        /* window width and height */
  223.         0,3,    /* detail and block pens */
  224.         GADGETDOWN+GADGETUP+CLOSEWINDOW+RAWKEY,    /* IDCMP flags */
  225.         WINDOWDRAG+WINDOWDEPTH+WINDOWCLOSE+ACTIVATE+NOCAREREFRESH+WINDOWSIZING,
  226.         &EjectGad,      /* first gadget in gadget list */
  227.         NULL,   /* custom CHECKMARK imagery */
  228.         (UBYTE *)"Sony LDP",    /* window title */
  229.         NULL,   /* custom screen pointer */
  230.         NULL,   /* custom bitmap */
  231.         144,12,    /* minimum width and height */
  232.         0,0,  /* maximum width and height */
  233.         WBENCHSCREEN    /* destination screen type */
  234. };
  235.  
  236.  
  237.  
  238. void UpdateDisplay(char *dstring, int how, int which)
  239. {
  240.   long              gadpos   ;
  241.   struct Gadget     *gadptr  ;
  242.   struct StringInfo *strgad  ;
  243.   char              *buffptr ;
  244.  
  245.   if (which == DTEXT) {
  246.     gadptr  = &TextDisplayGad ;
  247.     buffptr = (char *)TextBuff;
  248.   }
  249.   else {
  250.     gadptr  = &NumDisplayGad ;
  251.     buffptr = (char *)NumBuff;
  252.   };
  253.  
  254.   strgad=(struct StringInfo *)NumDisplayGad.SpecialInfo ;
  255.   gadpos = RemoveGadget(wp,gadptr) ; /* don't change before removing!  */
  256.   if (how == ADD) {                 /* add to existing string         */
  257.     if ((SHORT)strgad->NumChars < (NUMLEN-1)) {
  258.       strcat((char *)buffptr,dstring) ;
  259.     }
  260.     else strcpy((char *)buffptr,dstring) ; /* start over if too many! */
  261.   }
  262.   else {
  263.   strcpy((char *)buffptr,dstring) ;     /* new string              */
  264.   };
  265.   AddGadget(wp,gadptr,gadpos) ;
  266.   RefreshGList(gadptr,wp,NULL,gadpos) ;
  267. }
  268.  
  269.  
  270. void SetBaud(USHORT rate)      /* set baud rate and 8N1 */
  271. {
  272.   LONG  error ;
  273.  
  274.   if (rate>MAX_BAUD || rate<MIN_BAUD) rate=MIN_BAUD ;    /* simple error checking */
  275.   mySerReq->io_Baud     = rate       ;
  276.   mySerReq->io_ReadLen  = READ_BITS  ;
  277.   mySerReq->io_WriteLen = WRITE_BITS ;
  278.   mySerReq->io_StopBits = STOP_BITS  ;
  279.  
  280.   mySerReq->IOSer.io_Command = SDCMD_SETPARAMS ;
  281.   if ((error = DoIO((struct IORequest *)mySerReq)) != 0L) {
  282.     printf("SetBaud error = %ld\n",error) ;
  283.   };
  284. }
  285.  
  286. LONG ReadSer(char *data, USHORT length)
  287.  {
  288.    LONG              error = 0L ;
  289.    USHORT            i          ;
  290.  
  291.    for (i=0; i<MAXIN; inbuff[i]='\0',i++) ;   /* clear out in buffer */
  292.  
  293.    mySerReq->IOSer.io_Data = (APTR)data ;
  294.    mySerReq->IOSer.io_Length = (ULONG)length ;
  295.    mySerReq->IOSer.io_Command = CMD_READ ;
  296.  
  297.    if ((error = DoIO((struct IORequest *)mySerReq)) != 0L) {
  298.      printf("ReadSer err# %ld\n",error) ;
  299.    };
  300.    #ifdef DEBUG
  301.      printf("   ReadHex= %X %X %X %X %X \n",
  302.             inbuff[0],inbuff[1],inbuff[2],inbuff[3],inbuff[4]) ;
  303.    #endif
  304.    return (error) ;
  305.  }
  306.  
  307. LONG WriteSer(char c)
  308.  {
  309.    LONG  error      ;
  310.  
  311.    outbuff[0] = c   ;
  312.    outbuff[1] = '\0'; /* null terminate just in case! */
  313.    #ifdef DEBUG
  314.      printf("   SendChar= %s\n",outbuff) ;
  315.    #endif
  316.  
  317.    mySerReq->IOSer.io_Data = (APTR)outbuff ;   /* change to once only!! */
  318.    mySerReq->IOSer.io_Length = 1L   ;
  319.    mySerReq->IOSer.io_Command = CMD_WRITE ;
  320.  
  321.    if ((error = DoIO((struct IORequest *)mySerReq)) != 0L) {
  322.      printf("WriteSer err# %ld\n",error);
  323.    };
  324.    return (error) ;
  325.  }
  326.  
  327. LONG SendString(char *buff)
  328. {
  329.    LONG err,len  ;
  330.  
  331.    len = (long)strlen(buff) ;
  332.    #ifdef DEBUG
  333.      printf("   SendStr=%s\n",buff) ;
  334.    #endif
  335.  
  336.    mySerReq->IOSer.io_Data = (APTR)buff ;
  337.    mySerReq->IOSer.io_Length = len ;
  338.    mySerReq->IOSer.io_Command = CMD_WRITE ;
  339.  
  340.    if ((err = DoIO((struct IORequest *)mySerReq)) != 0L) {
  341.      printf("Write to serial port err# %ld\n",err);
  342.    };
  343.    return (err) ;
  344. }
  345.  
  346.  
  347. USHORT Ask_Sony_Model(UBYTE byt) /* returns LDP_1000A or OTHER or SLEEPING */
  348. {
  349.   LONG  err, count  ;
  350.   USHORT model, status = FALSE ;
  351.  
  352.   model  = (byt & D7) ;
  353.   if (model == 0) model = LDP_1000A ;
  354.   status = !(byt & NOT_READY) ;
  355.   if (status == FALSE) model = ASLEEP ;
  356.   return(model) ;
  357. }
  358.  
  359. void MyCleanup(USHORT err)
  360. {
  361.  if (err) printf("LDP stopped because: ERROR %s\n",ErrStr[err]) ;
  362.  if ( (CheckIO(mySerReq)==FALSE)&&(err != WRITEPORT_ERR) ) {
  363.    AbortIO((struct IORequest *)mySerReq) ; /* abort any pending requests */
  364.    WaitIO((struct IORequest *)mySerReq)  ;
  365.  };
  366.  if (SerDeviceACTIVE) CloseDevice((struct IORequest *)mySerReq) ;
  367.  if (wp != NULL) CloseWindow(wp) ;
  368.  if (IntuitionBase != NULL) CloseLibrary(IntuitionBase) ;
  369.  if (mySerReq != NULL) DeleteExtIO((struct IORequest *)mySerReq);
  370.  if (mySerPort != NULL) DeletePort(mySerPort) ;
  371.  if (rexx_port != NULL) DeletePort(rexx_port) ;
  372.  puts("   Please turn OFF the player when DONE!");
  373. }
  374.  
  375.  
  376. /* ARexx routines */
  377.  
  378. void SetupRexxPort(void)
  379. {
  380.    struct MsgPort *the_port=NULL ;
  381.  
  382.    Forbid() ;
  383.    if (FindPort(HOST_PORT_NAME)) {
  384.      Permit() ;
  385.      printf("A public port called '%s' already exists!\n",HOST_PORT_NAME) ;
  386.      the_port=NULL ;
  387.    }
  388.    the_port = CreatePort(HOST_PORT_NAME,0L) ;
  389.    Permit() ;
  390.  
  391.    if (the_port != NULL) {
  392.      RexxSigMask = (1L<<the_port->mp_SigBit) ;  /* setup signal bit */
  393.      rexx_port = the_port ;
  394.    }
  395.    else {
  396.      MyCleanup(REXX_ERR) ;
  397.      exit(FALSE) ;
  398.    }
  399. }
  400.  
  401. void ReplyRexxMessage(struct RexxMsg *rexxmessage, long result)
  402. {
  403.   rexxmessage->rm_Result1 = result ;
  404.   rexxmessage->rm_Result2 = 0L  ;
  405.   ReplyMsg((struct Message *)rexxmessage) ;
  406. }
  407.  
  408. void DoSimpleCmd(char *cmd)
  409. {
  410.  
  411.     strcpy(outbuff,cmd) ;              /* now build output buffer    */
  412.     strcat(outbuff,CmdTerm) ;
  413.     SendString(outbuff) ;            /* send string to serial port */
  414.     ReadSer(inbuff,ReturnBytes);    /* see what player returns    */
  415. }
  416.  
  417. void ClearSerialBuffer(void)
  418. {
  419.    ULONG   error ;
  420.  
  421.   mySerReq->IOSer.io_Command = CMD_CLEAR; /* clear out device buffer */
  422.   if ((error = DoIO((struct IORequest *)mySerReq)) != 0L) {
  423.     printf("Clear serial buffer error# %ld\n",error);
  424.   }
  425. }
  426.  
  427.  
  428. long GetAddress(char *cmd)     /* return player address as long int */
  429. {
  430.     USHORT x,*intp ;
  431.     int    y       ;
  432.     long   addr=0  ;
  433.  
  434.     ClearSerialBuffer() ;
  435.     /* now build output buffer */
  436.     strcpy(outbuff,cmd) ;                /* command                    */
  437.     strcat(outbuff,CmdTerm) ;           /* command terminator, if any */
  438.     SendString(outbuff) ;              /* send string to serial port */
  439.     ReadSer(inbuff,AddrBytes) ;       /* see what player returns    */
  440.     if(PlayerType == hitachi) {
  441.       intp = (USHORT *)(inbuff+1) ;    /* skip past echo, hi-lo bytes follow */
  442.       addr = (long)*intp ;            /* convert to long int                */
  443.       y = sprintf(CurrentAddr,"%ld\0",addr);        /* save addr as string */
  444.     }
  445.     else {
  446.       inbuff[5] = '\0' ;                      /* null terminate string      */
  447.       strcpy(CurrentAddr,inbuff);     /* save current address       */
  448.       addr = atol(inbuff) ;      /* convert string to signed long integer */
  449.     };
  450.     return(addr) ;
  451. }
  452.  
  453. void SetIndex(char *toggle)
  454. {
  455.     int  offset = on  ;    /* default */
  456.     char *cmd ;
  457.  
  458.     if (toggle != NULL) {
  459.       if(strncmp(toggle,indexstr[off],2L)==0) offset = off ;
  460.     };     /* now set a pointer to the correct index cmd */
  461.     cmd = Player[PlayerType].index[offset] ;
  462.     /* now build output buffer */
  463.     strcpy(outbuff,cmd) ;
  464.     strcat(outbuff,CmdTerm) ;         /* add any cmd terminator     */
  465.     SendString(outbuff) ;             /* send string to serial port */
  466.     ReadSer(inbuff,ReturnBytes);     /* see what player returns    */
  467.  
  468. }
  469.  
  470. void Step1KA(int direction)     /* Sony 1000A won't do single command stepping */
  471. {                              /* Actually the 2000 wouldn't either so all    */
  472.                               /* sonys now use this routine!                 */
  473.                              /* has problems when stepping near frame 1-2   */
  474.  
  475.     if (direction==FORWARD) {      /* forward step       */
  476.       WriteSer('=');        /* send F-STEP        */
  477.       ReadSer(inbuff,1) ;  /* expect ACK         */
  478.       WriteSer('O');      /* send STILL         */
  479.     }
  480.     else {   /* reverse step */
  481.       WriteSer('M');      /* send R-STEP       */
  482.       ReadSer(inbuff,1);
  483.       WriteSer('O');    /* send STILL command, last ReadSer from Go() */
  484.     }
  485. }
  486.  
  487.  
  488. void Go(int direction, char *speed) /* tried to be generic except for Step-1KA  */
  489. {
  490.   int    i=0,HowFast=0      ;
  491.   USHORT type=PlayerType,TotSpeeds=NUMSPEEDS-1 ;
  492.  
  493.   /* now change string into an index */
  494.   while ((i < TotSpeeds) && (strncmp(speed,speedstr[i],3L) !=0)) i++ ;
  495.   HowFast = i ;                            /* if no match, defaults to normal */
  496.   if (direction==FORWARD) strcpy(outbuff,Player[type].forward[HowFast]);
  497.   else strcpy(outbuff,Player[type].reverse[HowFast]);
  498.   strcat(outbuff,CmdTerm) ;  /* add any terminator */
  499.   if ((type==sony)&&(HowFast==step)) Step1KA(direction);
  500.   else SendString(outbuff) ;
  501.   ReadSer(inbuff,ReturnBytes) ;
  502. }
  503.  
  504.  
  505. void GoSearch(char *addr)
  506. {
  507.     char  *cmd,*temp,*fmode,*entercmd ;
  508.     long  num ;
  509.  
  510.     num = atol(addr) ;
  511.     if (num<1) addr="1" ;           /* error checking */
  512.     if (num>54000) addr="54000" ;
  513.  
  514.     cmd = Player[PlayerType].generic[search] ;       /* get the search cmd   */
  515.     fmode = PlayerMode ;                            /* get current mode cmd */
  516.     entercmd = Player[PlayerType].generic[enter];  /* get enter cmd        */
  517.  
  518.     if (ReversePolish == TRUE) {      /* pioneer players are like this    */
  519.       strcpy(outbuff,fmode) ;                 /* frame mode first        */
  520.       strcat(outbuff,addr) ;                 /* put address in second   */
  521.       strcat(outbuff,cmd)  ;                /* now add the command     */
  522.       strcat(outbuff,CmdTerm);             /* add any terminator      */
  523.       SendString(outbuff) ;               /* send the whole thing    */
  524.       ReadSer(inbuff,ReturnBytes);       /* expect R and CR         */
  525.     }
  526.     else {
  527.       if (PlayerType == sony) {           /* sony players         */
  528.         strcpy(ScratchBuff,fmode);       /* frame mode first     */
  529.         strcat(ScratchBuff,cmd)  ;      /* put command in next  */
  530.         strcat(ScratchBuff,addr) ;     /* now add the address  */
  531.         strcat(ScratchBuff,entercmd); /* add the enter cmd    */
  532.         strcat(ScratchBuff,CmdTerm) ;/* add terminator       */
  533.         for(temp=ScratchBuff; *temp!='\0'; temp++) {
  534.           WriteSer(*temp) ;             /* send single char     */
  535.           ReadSer(inbuff,ReturnBytes); /* expect ACK each time */
  536.         };
  537.         ReadSer(inbuff,1) ;  /* expect completion code */
  538.       }  /* end if sony */
  539.       else {                                /* hitachi players      */
  540.         strcpy(outbuff,cmd)  ;             /* put command in first */
  541.         strcat(outbuff,fmode) ;           /* frame mode next      */
  542.         strcat(outbuff,cmd)  ;           /* put command in next  */
  543.         strcat(outbuff,addr) ;          /* now add the address  */
  544.         strcat(outbuff,entercmd);      /* add the enter cmd    */
  545.         SendString(outbuff) ;         /* send the whole thing */
  546.         ReadSer(inbuff,2) ;     /* expect enter and job done */
  547.       }  /* else hitachi        */
  548.     }   /* else reverse polish */
  549. }      /* proc                */
  550.  
  551.  
  552.  
  553. BOOL CheckReady(void)
  554. {
  555.     char  *cmd ;
  556.     BOOL  ok=TRUE,myIO ;
  557.  
  558.  
  559.     ClearSerialBuffer() ;    /* make sure no garbage left over in buffer */
  560.     cmd = Player[PlayerType].generic[ready]  ;
  561.     /* now build output buffer */
  562.     strcpy(outbuff,cmd) ;         /* command                    */
  563.     strcat(outbuff,CmdTerm) ;    /* cmd terminator, if any     */
  564.     SendString(outbuff) ;       /* send string to serial port */
  565.  
  566.     mySerReq->IOSer.io_Data = (APTR)inbuff ;
  567.     mySerReq->IOSer.io_Length = (ULONG)StatBytes ;
  568.     mySerReq->IOSer.io_Command = CMD_READ ;
  569.  
  570.     SendIO((struct IORequest *)mySerReq) ;     /* asynchronous        */
  571.     Delay(4L) ;                               /* 4/60 sec delay      */
  572.     myIO = CheckIO((struct IORequest *)mySerReq) ;   /* see if done */
  573.     if (myIO == FALSE) {
  574.       Delay(600L) ;          /* wait about 10 more seconds */
  575.       myIO = CheckIO((struct IORequest *)mySerReq) ;
  576.       if (myIO == FALSE) {
  577.         AbortIO((struct IORequest *)mySerReq) ;
  578.         SonyModel = ASLEEP ;
  579.         return(FALSE) ;
  580.       }
  581.     } ;
  582.     GetMsg(mySerPort) ;  /* recycle message */
  583.  
  584.     switch (PlayerType) {
  585.       case sony     : /* Bit7 is zero for LDP-1000A */
  586.                       #ifdef DEBUG
  587.                         printf("   StatusIn= %d\n",*inbuff) ;
  588.                       #endif
  589.                       SonyModel = Ask_Sony_Model(inbuff[0]) ;
  590.                       if (SonyModel == ASLEEP) ok = FALSE   ;
  591.                       break ;
  592.  
  593.       case hitachi  : ok = TRUE ;   /* no ready status available! */
  594.                       break ;
  595.  
  596.       case pioneer  : /* buffer contents might be P01,P02,P06,etc. */
  597.                       #ifdef DEBUG
  598.                       printf("   StatusIn= %s\n",inbuff) ;
  599.                       #endif
  600.                    /* if (inbuff[2] < '4') ok = FALSE ;  */
  601.                       ok = TRUE ;  /* Don't look at what is returned! */
  602.                       break ;
  603.  
  604.       default       : break ;
  605.  
  606.     } ;
  607.     return (ok) ;
  608. }
  609.  
  610. void InitPlayer(void)
  611. {
  612.  char  *temp, *MyInit ;
  613.  
  614.  if (PlayerType != none) {
  615.     SetBaud(BaudRate) ;
  616.     ReversePolish = Player[PlayerType].rp ;      /* as in PIONEER!            */
  617.     CmdTerm = Player[PlayerType].term ;         /* set up command terminator */
  618.     PlayerMode = Player[PlayerType].generic[frame]; /* frame mode default   */
  619.     ReturnBytes = Player[PlayerType].returnbytes;  /* command return bytes */
  620.     StatBytes = Player[PlayerType].statbytes;  /* # status bytes returned */
  621.     AddrBytes = Player[PlayerType].addrbytes; /* # address ''    ''      */
  622.     MyInit    = Player[PlayerType].generic[init] ;
  623.  
  624.     if (PlayerType==hitachi) DoSimpleCmd(MyInit) ;
  625.     LdpREADY = CheckReady() ;
  626.     if (LdpREADY) {
  627.       if (PlayerType != sony) Go(FORWARD,"normal") ;   /* spin it up           */
  628.       if (PlayerType == pioneer) DoSimpleCmd(MyInit);
  629.       if (PlayerType == sony) {     /* can't send whole string at once */
  630.         for (temp=MyInit; *temp != '\0'; temp++) {
  631.           WriteSer(*temp) ;             /* send single char     */
  632.           ReadSer(inbuff,ReturnBytes); /* expect ACK each time */
  633.         }
  634.       }
  635.       SetIndex("on") ;                    /* set on-screen display       */
  636.       GoSearch("1")  ;                   /* now go to first frame       */
  637.     }
  638.  }
  639.  else LdpREADY = FALSE ;
  640. }
  641.  
  642. void PlaySequence(char *start,char *end)  /* I got tired of being GENERIC! */
  643. {                                        /* The following is BRUTE FORCE! */
  644.  
  645.     char    *temp,*entercmd,*searchcmd,*repeatcmd,*playcmd,*mem1 ;
  646.     USHORT  x ;
  647.     long    startnum,endnum ;
  648.  
  649.     entercmd  = Player[PlayerType].generic[enter]  ;
  650.     searchcmd = Player[PlayerType].generic[search] ;
  651.     repeatcmd = Player[PlayerType].generic[repeat] ;
  652.     mem1      = Player[PlayerType].special1        ; /* hitachi */
  653.  
  654.     startnum = atol(start) ;
  655.     endnum   = atol(end)   ;
  656.     if (startnum<1) start="1" ;           /* error checking */
  657.     if (startnum>54000) start="27000" ;
  658.     if (endnum<1) end ="1" ;
  659.     if (endnum>54000) end="27000" ;
  660.     startnum = atol(start) ;
  661.     endnum   = atol(end)   ;
  662.  
  663.     switch (PlayerType) {
  664.  
  665.       case sony  :
  666.         SendString(PlayerMode) ;
  667.         ReadSer(inbuff,1) ;
  668.         SendString(searchcmd)  ;
  669.         ReadSer(inbuff,1) ;
  670.         for(temp=start; *temp!='\0'; temp++) {
  671.           WriteSer(*temp) ;     /* send single char     */
  672.           ReadSer(inbuff,1);   /* expect ACK each time */
  673.         };
  674.         SendString(entercmd) ;
  675.         ReadSer(inbuff,1) ;
  676.         ReadSer(inbuff,1) ;   /* expect completion code */
  677.         SendString(repeatcmd) ;
  678.         ReadSer(inbuff,1) ;
  679.         for(temp=end; *temp!='\0'; temp++) {
  680.           WriteSer(*temp) ;     /* send single char     */
  681.           ReadSer(inbuff,1);   /* expect ACK each time */
  682.         };
  683.         SendString(entercmd) ;
  684.         ReadSer(inbuff,1) ;
  685.         SendString("1") ;
  686.         ReadSer(inbuff,1) ;
  687.         SendString(entercmd) ;
  688.         ReadSer(inbuff,1) ;
  689.         ReadSer(inbuff,1) ;   /* get completion code */
  690.         break ;
  691.  
  692.       case pioneer :   /* ok to send up to 20 char in one command, CR terminated */
  693.         if (startnum < endnum) playcmd = Player[pioneer].forward[normal] ;
  694.         else                   playcmd = Player[pioneer].reverse[normal] ;
  695.         strcpy(outbuff,PlayerMode) ;         /* frame mode               */
  696.         strcat(outbuff,start) ;             /* put search address       */
  697.         strcat(outbuff,searchcmd);         /* put SEarch command       */
  698.         strcat(outbuff,CmdTerm)  ;        /*  CR terminator           */
  699.         SendString(outbuff);
  700.         ReadSer(inbuff,ReturnBytes);
  701.         strcpy(outbuff,end);              /* put play to address      */
  702.         strcat(outbuff,"SM");            /* Stop Marker              */
  703.         strcat(outbuff,playcmd) ;       /* put multi-speed command  */
  704.         strcat(outbuff,CmdTerm) ;      /* terminate command (CR)   */
  705.         SendString(outbuff)     ;     /* send commands to player  */
  706.         ReadSer(inbuff,ReturnBytes); /* expect back R and CR     */
  707.         break ;
  708.  
  709.       case hitachi : /* ok to send as a string */
  710.         strcpy(outbuff,searchcmd) ;         /* search command first      */
  711.         strcat(outbuff,PlayerMode);        /* frame command next        */
  712.         strcat(outbuff,start)     ;       /* now start address         */
  713.         strcat(outbuff,mem1)      ;      /* remember this location    */
  714.         strcat(outbuff,end)       ;     /* now end address           */
  715.         strcat(outbuff,entercmd)  ;    /* terminate with enter      */
  716.         SendString(outbuff)       ;   /* send it out               */
  717.         ReadSer(inbuff,2)         ;  /* expect ENTER & JOB END    */
  718.         break ;                     /* JOB END = SEARCH+80H      */
  719.  
  720.       default       :
  721.         break ;
  722.     }  /* switch */
  723. }     /* proc   */
  724.  
  725.  
  726. long DoCommand(char *cmd, char *arg1, char *arg2)
  727. {
  728.   int  c=0,i   ;
  729.   long result= 0   ;
  730.   char *current= NULL ;  /* pointer to current command */
  731.  
  732.   /* now check only the 1st 3 letters of command and increment cmd index */
  733.   while ((c < NUMCMDS) && (strncmp(cmd, VideoCmd[c],3) != 0)) c++ ;
  734.   CurrentCmd = c ; /* global variable, use to index into generic commands */
  735.   current = Player[PlayerType].generic[CurrentCmd];
  736.   switch (c) {
  737.  
  738.     case address    :   if (LdpREADY) {
  739.                           result = GetAddress(current) ;
  740.                         };
  741.                         break ;
  742.  
  743.  
  744.     case baud       :  /* set baud rate of AMIGA serial port */
  745.                       /* laser player should MATCH rate!    */
  746.                      /* usual rates are  1200,4800,9600    */
  747.                       if (arg1 != NULL) {
  748.                         BaudRate = (USHORT)atoi(arg1); /* convert str->int */
  749.                         SetBaud(BaudRate)       ;
  750.                       } ;
  751.                       result = (long)BaudRate ;  /* return long integer */
  752.                       break ;
  753.  
  754.     case clear      :   if (LdpREADY) {
  755.                           ClearSerialBuffer()  ;
  756.                           DoSimpleCmd(current) ;
  757.                         };
  758.                         break ;
  759.  
  760.     case eject      :   if (LdpREADY) DoSimpleCmd(current) ;
  761.                         break ;
  762.  
  763.     case enter      :   if (LdpREADY) DoSimpleCmd(current) ;
  764.                         break ;
  765.  
  766.     case forward    :   if (LdpREADY) Go(FORWARD,arg1) ;
  767.                         break ;
  768.  
  769.     case frame      :   if (LdpREADY) DoSimpleCmd(current) ;
  770.                         break ;
  771.  
  772.     case index      :   if (LdpREADY) SetIndex(arg1) ;
  773.                         break ;
  774.  
  775.     case init       :   InitPlayer() ;
  776.                         result = (long)LdpREADY ;
  777.                         break ;
  778.  
  779.     case play       :   if (LdpREADY) PlaySequence(arg1,arg2) ;
  780.                         break ;
  781.  
  782.     case quit       :   TimeToExit = TRUE ;  /* shutdown the program */
  783.                         break ;             /* useful if no remote! */
  784.  
  785.     case ready      :   result = (long)CheckReady() ;
  786.                         break ;
  787.  
  788.     case reverse    :   if (LdpREADY) Go(REVERSE,arg1) ;
  789.                         break ;
  790.  
  791.     case search     :   if (LdpREADY) GoSearch(arg1) ;
  792.                         break ;
  793.  
  794.  
  795.     case still      :   if (LdpREADY) DoSimpleCmd(current)  ;
  796.                         break ;
  797.  
  798.     case vplayer    :  /* select video player type                      */
  799.                       /* echo back or return current player if no arg1 */
  800.                       if(arg1 != NULL) {
  801.                        result = (long)(*arg1); /* echo char if not illegal */
  802.                         switch(*arg1) {  /*  *arg1 is 1st char of string! */
  803.                           case 's' : PlayerType = sony ;
  804.                                      InitPlayer()   ;
  805.                                      break ;
  806.                           case 'p' : PlayerType = pioneer ;
  807.                                      InitPlayer() ;
  808.                                      break ;
  809.                           case 'h' : PlayerType = hitachi ;
  810.                                      InitPlayer() ;
  811.                                      break ;
  812.                           case 'n' : PlayerType = none    ;
  813.                                      LdpREADY = FALSE     ;
  814.                                      break ;
  815.                           default  : result = (long)*PlayerStr[PlayerType] ;
  816.                                      break ; /* return current if illegal */
  817.                         }  /* switch */
  818.                       }   /* if     */
  819.                       else result = (long)*PlayerStr[PlayerType] ;
  820.                       if(wp!=NULL)SetWindowTitles(wp,PlayerStr[PlayerType],NULL);
  821.                       break ;
  822.  
  823.  
  824.     default         :   puts("ILLEGAL command!!") ;
  825.                         result = 255L ;
  826.                         break ;
  827.  
  828.   };
  829.   return(result) ;
  830. }
  831.  
  832. void execute_command(struct RexxMsg *rexxmessage)
  833. {
  834.   char    *token[4], *temp  ;        /* token[0]=Command, others=arguments   */
  835.   int     err               ;       /* this routine crashes system if total */
  836.   USHORT  x                 ;      /* tokens not 1 greater!                */
  837.   long    result=0          ;     /* eg: cmd arg1 arg2    tokens=3+1      */
  838.  
  839.   for (x=0; x<4; token[x]=NULL,x++) ;     /* clear out token buffer */
  840.   token[0] = (char *)rexxmessage->rm_Args[0] ;     /* parse ARexx string, */
  841.   token[0] = strtok(token[0],(char *)" ,") ;      /* look for space or , */
  842.   for (x=1; (token[x] = strtok(NULL,(char *)" ,")) != NULL; x++) ;
  843.   for (x=0; x<4; x++) {               /* convert all strings to lower-case */
  844.     strlwr(token[x]) ;
  845.   } ;
  846.   result = DoCommand(token[0],token[1],token[2]) ;
  847.   ReplyRexxMessage(rexxmessage,result) ;
  848. }
  849.  
  850. /*  Process Gadgets  */
  851.  
  852. void ProcessGadgetUp(USHORT mygad)
  853. {
  854.     char   *addrcmd=Player[PlayerType].generic[address]  ;
  855.     char   ThisChar[2], *num, PriorStr[TEXTLEN] ;
  856.     LONG   temp      ;
  857.     FILE   *NoteFile ;
  858.  
  859.     switch (mygad) {
  860.  
  861.       case Memorize   :    strcpy(PriorStr,(char *)TextBuff); /* save prior info */
  862.                            UpdateDisplay(GadStr[mygad],NEW,DTEXT) ;
  863.                            temp=GetAddress(addrcmd) ;
  864.                            addrcmd=strcpy(MemAddr,CurrentAddr); /* save MemAddr */
  865.                            UpdateDisplay(MemAddr,NEW,DNUM) ;
  866.                            Delay(30L) ;
  867.                            UpdateDisplay(PriorStr,NEW,DTEXT) ;
  868.                            break ;
  869.  
  870.       case Msearch    :    UpdateDisplay(MemAddr,NEW,DNUM) ;
  871.                            UpdateDisplay(GadStr[mygad],NEW,DTEXT) ;
  872.                            GoSearch(MemAddr) ;
  873.                            break ;
  874.  
  875.       case Log        :    strcpy(PriorStr,(char *)TextBuff) ;     /* save note */
  876.                            UpdateDisplay(GadStr[mygad],NEW,DTEXT) ; /* logging */
  877.                            temp=GetAddress(addrcmd) ; /* show current address */
  878.                            UpdateDisplay(CurrentAddr,NEW,DNUM) ;
  879.                            NoteFile = fopen("ram:LDP.log","a") ; /* save to file */
  880.                            fprintf(NoteFile,"%s  %s\n",CurrentAddr,PriorStr) ;
  881.                            fclose(NoteFile) ;
  882.                            Delay(30L) ;
  883.                            UpdateDisplay(PriorStr,NEW,DTEXT) ; /* reshow note */
  884.                            break ;
  885.  
  886.  
  887.       case Index      :    IndexON ^= TRUE ;                /* toggle on/off */
  888.                            if (IndexON) SetIndex("on");
  889.                            else SetIndex("off");
  890.                            break ;
  891.  
  892.       case NumDisplay :    if (PlayerType == pioneer) {
  893.                              UpdateDisplay("Search",NEW,DTEXT) ;
  894.                              SearchPRESSED = TRUE ;
  895.                              GoSearch((char *)NumBuff) ;
  896.                            }
  897.                            else {
  898.                              if (SearchPRESSED) {
  899.                                SearchPRESSED = FALSE ;
  900.                                UpdateDisplay(GadStr[Enter],NEW,DTEXT) ;
  901.                                if (PlayerType == hitachi) {
  902.                                  SendString((char *)NumBuff) ;
  903.                                }
  904.                                else {        /* sony players */
  905.                                  for (num=(char *)NumBuff; *num !='\0'; num++) {
  906.                                    WriteSer(*num) ;
  907.                                    ReadSer(inbuff,1) ;
  908.                                  }
  909.                                };
  910.                                SendString(Player[PlayerType].generic[enter]);
  911.                                /* expect back ACK,COMPLETION or ECHO,JOB DONE */
  912.                                ReadSer(inbuff,2) ;
  913.                              }
  914.                              else {
  915.                                UpdateDisplay("Search/Enter",NEW,DTEXT) ;
  916.                                GoSearch((char *)NumBuff) ;
  917.                              }
  918.                            };
  919.                            break ;
  920.  
  921.  
  922.       case Search     :    if ((SearchPRESSED==TRUE) && (PlayerType!=pioneer)) {
  923.                              UpdateDisplay("ERROR!",NEW,DTEXT) ;
  924.                              break ;
  925.                            };
  926.                            UpdateDisplay(GadStr[mygad],NEW,DTEXT) ;
  927.                            SearchPRESSED = TRUE ;
  928.                            if (PlayerType != pioneer) UpdateDisplay("",NEW,DNUM);
  929.                            else SendString((char *)NumBuff);
  930.                            DoSimpleCmd(Player[PlayerType].generic[search]);
  931.                            if (PlayerType == hitachi) {
  932.                              DoSimpleCmd(Player[hitachi].generic[frame]) ;
  933.                            };
  934.                            break ;
  935.  
  936.       case Still      :    UpdateDisplay(GadStr[mygad],NEW,DTEXT) ;
  937.                            DoSimpleCmd(Player[PlayerType].generic[still]) ;
  938.                            Delay(1L) ;
  939.                            temp=GetAddress(addrcmd) ; /* show current address */
  940.                            UpdateDisplay(CurrentAddr,NEW,DNUM) ;
  941.                            break ;
  942.  
  943.  
  944.       case Clear      :    UpdateDisplay(GadStr[mygad],NEW,DTEXT) ;
  945.                            UpdateDisplay("",NEW,DNUM)  ;
  946.                            ClearSerialBuffer() ;
  947.                            DoSimpleCmd(Player[PlayerType].generic[clear]) ;
  948.                            SearchPRESSED = FALSE ;
  949.                            break ;
  950.  
  951.       case Enter      :    UpdateDisplay(GadStr[mygad],NEW,DTEXT);
  952.                            if (SearchPRESSED) {   /* send buff next */
  953.                              SearchPRESSED = FALSE ;
  954.                              if (PlayerType == hitachi) {
  955.                                SendString((char *)NumBuff) ;
  956.                              }
  957.                              else {        /* for sony: send single chars  */
  958.                                for (num=(char *)NumBuff; *num !='\0'; num++) {
  959.                                  WriteSer(*num) ;
  960.                                  ReadSer(inbuff,1) ;
  961.                                }
  962.                              };
  963.                              SendString(Player[PlayerType].generic[enter]);
  964.                              /* expect back ACK,COMPLETION or ECHO,JOB DONE */
  965.                              ReadSer(inbuff,2) ;
  966.                            }
  967.                            else UpdateDisplay("ERROR!",NEW,DTEXT) ;
  968.                            break ;
  969.  
  970.       case Eject      :    UpdateDisplay(GadStr[mygad],NEW,DTEXT) ;
  971.                            DoSimpleCmd(Player[PlayerType].generic[eject]) ;
  972.                            break ;
  973.  
  974.  
  975.       case Fplay      :    UpdateDisplay(GadStr[mygad],NEW,DTEXT) ;
  976.                            Go(FORWARD,"normal") ;
  977.                            break ;
  978.  
  979.       case Rplay      :    UpdateDisplay(GadStr[mygad],NEW,DTEXT) ;
  980.                            Go(REVERSE,"normal") ;
  981.                            break ;
  982.  
  983.       case Fslow      :    UpdateDisplay(GadStr[mygad],NEW,DTEXT) ;
  984.                            Go(FORWARD,"slow")  ;
  985.                            break ;
  986.  
  987.       case Rslow      :    UpdateDisplay(GadStr[mygad],NEW,DTEXT) ;
  988.                            Go(REVERSE,"slow") ;
  989.                            break ;
  990.  
  991.       case Ffast      :    UpdateDisplay(GadStr[mygad],NEW,DTEXT) ;
  992.                            Go(FORWARD,"fast") ;
  993.                            break ;
  994.  
  995.       case Rfast      :    UpdateDisplay(GadStr[mygad],NEW,DTEXT) ;
  996.                            Go(REVERSE,"fast") ;
  997.                            break ;
  998.  
  999.       case Fscan      :    FscanDOWN = FALSE ; /* scan button UP is still frame */
  1000.                            DoSimpleCmd(Player[PlayerType].generic[still]) ;
  1001.                            Delay(4L) ;
  1002.                            temp=GetAddress(addrcmd) ; /* show current address */
  1003.                            UpdateDisplay(CurrentAddr,NEW,DNUM) ;
  1004.                            break ;
  1005.  
  1006.       case Rscan      :    RscanDOWN = FALSE ;
  1007.                            DoSimpleCmd(Player[PlayerType].generic[still]) ;
  1008.                            Delay(4L) ;
  1009.                            temp=GetAddress(addrcmd) ; /* show current address */
  1010.                            UpdateDisplay(CurrentAddr,NEW,DNUM) ;
  1011.                            break ;
  1012.  
  1013.       case Fstep      :    UpdateDisplay(GadStr[mygad],NEW,DTEXT) ;
  1014.                            Go(FORWARD,"step");
  1015.                            Delay(1L) ;
  1016.                            temp=GetAddress(addrcmd) ; /* show current address */
  1017.                            UpdateDisplay(CurrentAddr,NEW,DNUM) ;
  1018.                            break ;
  1019.  
  1020.       case Rstep      :    UpdateDisplay(GadStr[mygad],NEW,DTEXT) ;
  1021.                            Go(REVERSE,"step");
  1022.                            Delay(1L) ;
  1023.                            temp=GetAddress(addrcmd) ; /* show current address */
  1024.                            UpdateDisplay(CurrentAddr,NEW,DNUM) ;
  1025.                            break ;
  1026.  
  1027.       case Zero: case One: case Two: case Three: case Four:
  1028.         ThisChar[0] = (mygad+48) ;
  1029.         ThisChar[1] = '\0' ;
  1030.         UpdateDisplay(ThisChar,ADD,DNUM) ; /* accumulate chars in NumBuff */
  1031.         break ;
  1032.  
  1033.       case Five: case Six: case Seven: case Eight: case Nine:
  1034.         ThisChar[0] = (mygad+48) ;
  1035.         ThisChar[1] = '\0' ;
  1036.         UpdateDisplay(ThisChar,ADD,DNUM) ;
  1037.         break ;
  1038.  
  1039.  
  1040.       default         :     break ;
  1041.  
  1042.     }    /* switch */
  1043. }       /* proc   */
  1044.  
  1045.  
  1046. void ProcessGadgetDown(USHORT mygad)
  1047.   {
  1048.    switch (mygad) {
  1049.  
  1050.      case Fscan   :  UpdateDisplay("Fscan   ",NEW,DTEXT) ;
  1051.                      FscanDOWN = TRUE ;
  1052.                      Go(FORWARD,"scan") ;
  1053.                      break ;
  1054.  
  1055.      case Rscan   :  UpdateDisplay("Rscan   ",NEW,DTEXT) ;
  1056.                      RscanDOWN = TRUE ;
  1057.                      Go(REVERSE,"scan") ;
  1058.                      break ;
  1059.  
  1060.      default      :  break ;
  1061.  
  1062.    }  /* switch */
  1063.   }  /* proc   */
  1064.  
  1065. void ProcessEvents(void)
  1066. {
  1067.     struct IntuiMessage *eventptr    ;
  1068.     struct RexxMsg      *rexxmessage ;
  1069.     ULONG               class        ;
  1070.     USHORT              code, mygad  ;
  1071.     struct Gadget       *GadPtr      ;
  1072.     SHORT               y            ;
  1073.  
  1074.   while (!TimeToExit)  {
  1075.  
  1076.     wakeupmask = Wait(UserSigMask | RexxSigMask) ; /* now wait for events... */
  1077.  
  1078.     if (wakeupmask & RexxSigMask) {               /* process Rexx commands */
  1079.       while ( (rexxmessage = (struct RexxMsg *)GetMsg(rexx_port)) ) {
  1080.         execute_command(rexxmessage)   ;
  1081.       }
  1082.     } ;
  1083.  
  1084.     if (wakeupmask & UserSigMask) {  /* process remote controller commands */
  1085.       while ( (eventptr = (struct IntuiMessage *)GetMsg(wp->UserPort)) ) {
  1086.  
  1087.         class  = eventptr->Class    ;
  1088.         code   = eventptr->Code     ;       /* Save values of interest */
  1089.         GadPtr = (struct Gadget *)eventptr->IAddress ;
  1090.         y      = eventptr->MouseY   ;
  1091.  
  1092.         ReplyMsg( (struct Message *) eventptr ) ; /* Reply QUICKLY! */
  1093.         mygad = GadPtr->GadgetID ;
  1094.  
  1095.         switch (class)  {
  1096.  
  1097.           case GADGETUP    :   if (LdpREADY) {
  1098.                                  ProcessGadgetUp(mygad) ;
  1099.                                };
  1100.                                break ;
  1101.  
  1102.           case GADGETDOWN  :   if (LdpREADY) {
  1103.                                  ProcessGadgetDown(mygad) ;
  1104.                                };
  1105.                                break ;
  1106.  
  1107.           case CLOSEWINDOW :   TimeToExit = TRUE ;
  1108.                                break ;
  1109.  
  1110.           case RAWKEY      :   if (code == HELP) printf("%s",HelpStr) ;
  1111.                                break ;
  1112.  
  1113.           default          :   break ;
  1114.  
  1115.         }    /* switch            */
  1116.       }     /* while             */
  1117.     }      /* if UserSigMask    */
  1118.   } ;     /* while timetoexit  */
  1119.  
  1120.   while ( (eventptr = (struct IntuiMessage *)GetMsg(wp->UserPort)) ) {
  1121.     ReplyMsg( (struct Message *) eventptr ) ;  /* clear out intuition messages */
  1122.   };
  1123.   while ( (rexxmessage = (struct RexxMsg *)GetMsg(rexx_port)) ) {
  1124.     ReplyMsg( (struct Message *) rexxmessage) ; /* clear out arexx messages */
  1125.   }
  1126. }    /* proc   */
  1127.  
  1128.  
  1129. void SetupPorts(void)
  1130. { LONG      i, error,unit=(long)SerialUnit ;
  1131.   BYTE      *b, *c ;
  1132.  
  1133.   mySerPort = CreatePort("mySerialPort",0L) ;
  1134.   if (mySerPort == NULL) {
  1135.     MyCleanup(WRITEPORT_ERR) ;
  1136.     exit(FALSE) ;
  1137.   };
  1138.   i = (LONG)sizeof(struct IOExtSer) ;
  1139.   mySerReq = (struct IOExtSer *)CreateExtIO(mySerPort,i) ;
  1140.   if (mySerReq == NULL) {
  1141.     MyCleanup(READ_EXTIO_ERR) ;
  1142.     exit(FALSE) ;
  1143.   } ;
  1144.   mySerReq->io_SerFlags = (SERF_RAD_BOOGIE | SERF_7WIRE);         /* FAST I/O! */
  1145.   error = OpenDevice("serial.device",unit,(struct IORequest *)mySerReq,0L) ;
  1146.   if (error != 0) {
  1147.     MyCleanup(DEVICE_ERR) ;
  1148.     exit(FALSE) ;
  1149.   }
  1150.   else SerDeviceACTIVE = TRUE ;
  1151. }
  1152.  
  1153.  
  1154. void OpenLibs(void)
  1155. {
  1156.   IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",0L);
  1157.   if (IntuitionBase == NULL) {
  1158.     MyCleanup(INT_ERR) ;
  1159.     exit(FALSE) ;
  1160.   }
  1161. }
  1162.  
  1163. void InitWindow(void)
  1164. {
  1165.   LdpWindow.Title = (UBYTE *)PlayerStr[PlayerType] ;
  1166.   if (SonyModel == LDP_1000A) LdpWindow.Title = (UBYTE *)"SONY-1KA" ;
  1167.   if (LdpREADY == FALSE) {
  1168.     strcpy(ScratchBuff,(char *)LdpWindow.Title) ;
  1169.     strcat(ScratchBuff," ASLEEP!") ;
  1170.     LdpWindow.Title = (UBYTE *)ScratchBuff ;
  1171.   } ;
  1172.   if ((wp = OpenWindow(&LdpWindow)) == NULL) {
  1173.     MyCleanup(WIN_ERR) ;
  1174.     exit(FALSE) ;
  1175.   } ;
  1176.   if (PlayerType == pioneer) OffGadget(&EnterGad,wp,NULL); /* disable Enter */
  1177.   if (LdpREADY != TRUE) UpdateDisplay("RESTART!",NEW,DTEXT) ;
  1178.   UserSigMask  =  (1L << wp->UserPort->mp_SigBit) ; /* set up signal for events */
  1179. }
  1180.  
  1181. void SetPlayer(char *type)
  1182. {
  1183.       switch (*type) {  /* look at first character */
  1184.         case 's' : PlayerType = sony ;
  1185.                    break ;
  1186.         case 'p' : PlayerType = pioneer ;
  1187.                    break ;
  1188.         case 'h' : PlayerType = hitachi ;
  1189.                    break ;
  1190.         case 'n' : PlayerType = none    ;
  1191.                    break ;
  1192.         default  : PlayerType = sony    ;    /* default player is sony */
  1193.                    break ;
  1194.       }  /* switch */
  1195. }
  1196.  
  1197. void ParseCmdLine(char *arg[])        /* global variables will be modified */
  1198. {
  1199.   USHORT i ;
  1200.   char   *temp,*baud,*remote,*player,*unit ;
  1201.  
  1202.   if (strcmp(arg[1],"?")==0) {      /* give help */
  1203.     printf("%s",HelpStr) ;
  1204.     arg[1]="-pnone"      ;
  1205.   };
  1206.   for (i=0; arg[i] != NULL ; i++) {  /* convert to lower-case first */
  1207.     for (temp = arg[i]; *(temp) != '\0'; temp++) *temp=tolower(*temp) ;
  1208.     if ((baud = strchr(arg[i],'b'))!= NULL) {  /* look for baud rate */
  1209.       baud++ ;  /* increment pointer past 'b' */
  1210.       BaudRate = (USHORT)atoi(baud) ; /* convert string to integer value */
  1211.     } ;
  1212.     if ((player = strchr(arg[i],'p'))!= NULL) { /* look for player name */
  1213.       player++ ; /* increment pointer past 'p' */
  1214.       SetPlayer(player) ;
  1215.     };  /* if     */
  1216.     if ((remote = strchr(arg[i],'r'))!= NULL) {  /* look for remote toggle*/
  1217.       remote++ ; /* increment pointer past 'r' */
  1218.       if (strncmp(remote,indexstr[off],2L)==0) RemoteON = FALSE ;
  1219.     };
  1220.     if ((unit = strchr(arg[i],'u'))!= NULL) {   /* look for serial unit#      */
  1221.       unit++ ;                                 /* increment pointer past 'u' */
  1222.       SerialUnit = (USHORT)atoi(unit) ;       /* convert str to integer     */
  1223.       if (SerialUnit < MIN_UNIT || SerialUnit > MAX_UNIT) SerialUnit = MIN_UNIT ;
  1224.     }  /* if       */
  1225.   }   /* for loop */
  1226. }    /* proc     */
  1227.  
  1228. void GetTooltypes(struct WBStartup *msg)
  1229. {
  1230.  struct WBArg      *arg ;
  1231.  struct DiskObject *diskobj ;
  1232.  char              **toolarray ; /* pointer to an array of string pointers */
  1233.  char              *value      ;
  1234.  
  1235.  if ((IconBase = OpenLibrary(ICONNAME,1L)) == NULL) {
  1236.    MyCleanup(ILIB_ERR) ;
  1237.    exit(FALSE) ;
  1238.  };
  1239.  arg=msg->sm_ArgList;         /* get argument list from WB startup msg     */
  1240.  diskobj = GetDiskObject(arg->wa_Name) ;        /* now get info from icon */
  1241.  toolarray = diskobj->do_ToolTypes  ;          /* setup ToolType array   */
  1242.  value = FindToolType(toolarray,"PLAYER") ;
  1243.  strlwr(value) ;                           /* convert to lower case */
  1244.  SetPlayer(value) ;                       /* setup player type     */
  1245.  value = FindToolType(toolarray,"BAUD") ;
  1246.  BaudRate = (USHORT)atoi(value) ;         /* setup baud rate    */
  1247.  if (BaudRate == 0) BaudRate = MIN_BAUD ;
  1248.  value = FindToolType(toolarray,"REMOTE") ;
  1249.  if (stricmp(value,"OFF")==0) RemoteON = FALSE ;  /* setup onscreen display */
  1250.  else RemoteON = TRUE ;
  1251.  value = FindToolType(toolarray,"UNIT") ;
  1252.  SerialUnit = (USHORT)atoi(value) ;            /* setup serial unit#      */
  1253.  if (SerialUnit < MIN_UNIT || SerialUnit > MAX_UNIT) SerialUnit = MIN_UNIT ;
  1254.  
  1255.  FreeDiskObject(diskobj);      /* cleanup */
  1256.  CloseLibrary(IconBase) ;
  1257. }
  1258.  
  1259.  
  1260. /*  *******  MAIN  PROGRAM  ******  */
  1261.  
  1262. main(int argc, char *argv[])
  1263. {
  1264.  
  1265.   puts("") ;
  1266.   if (argc > 1) ParseCmdLine(argv) ;                       /* cmd line startup  */
  1267.   else if (argc == 0) GetTooltypes((struct WBStartup *)argv) ;  /* WB startup  */
  1268.   puts("   Default is SONY 1200Baud RemoteON") ;
  1269.  
  1270.   OpenLibs() ;
  1271.   SetupPorts()  ;
  1272.   ClearSerialBuffer() ;
  1273.   SetupRexxPort() ;
  1274.  
  1275.   puts("   Waiting......") ;
  1276.   InitPlayer()  ;
  1277.   if (RemoteON) InitWindow() ;                   /* show controller on screen */
  1278.   if (!LdpREADY) puts("   Need to RESTART!") ;
  1279.   else puts("   Player READY!") ;
  1280.  
  1281.   ProcessEvents() ;                            /* Main loop */
  1282.   MyCleanup(NO_ERR) ;
  1283.  
  1284. }
  1285.